home *** CD-ROM | disk | FTP | other *** search
/ HyperLib 1997 Winter - Disc 1 / HYPERLIB-1997-Winter-CD1.ISO.7z / HYPERLIB-1997-Winter-CD1.ISO / オンラインウェア / UTIL / Folder・Icon・Opener 1.0.1.sit / Folder•Icon•Opener 1.0.1 / source code / sources / FIOpen.finder.c < prev    next >
Text File  |  1996-05-05  |  12KB  |  382 lines

  1. /*
  2.  *--------------------------------------------------------------
  3.  * FIOpen.finder.c
  4.  *--------------------------------------------------------------
  5.  *    Copyright ゥ Fumio Rokkaku, 1996
  6.  *--------------------------------------------------------------
  7.  */
  8. #pragma once
  9.  
  10. /* System Headers */
  11. #include <Memory.h>
  12. #include <Files.h>
  13. #include <Folders.h>
  14. #include <Finder.h>
  15. #include <Aliases.h>
  16. #include <Icons.h>
  17. #include <Processes.h>
  18. #include <AppleEvents.h>
  19. #include <AERegistry.h>
  20. #include <AEPackObject.h>
  21. #include <OSUtils.h>
  22.  
  23. /* Project Headers */
  24. #include "FIOpen.h"
  25.  
  26. /*
  27.  *--------------------------------------------------------------
  28.  *    Finder specific constant definitions
  29.  *--------------------------------------------------------------
  30.  */
  31. enum FinderRegistries{
  32.     kFinderSign        = 'MACS',        /* Finder signature */
  33.     kFinderType        = 'FNDR',        /* Finder type */
  34.     kAEUpdate        = 'fupd',        /* from Apple's FinderRegistry.h */
  35.     pIconBitmap        = 'iimg',        /* icon bitmap property */
  36.     pOriginalItem    = 'orig',        /* item pointed to by alias */
  37.     pCreatorType    = 'fcrt',        /* file creator property */
  38.     pFileType        = 'fitp',        /* file type  property*/
  39.     pVersion2        = 'ver2',        /* file version property*/
  40.     pLabelIndex        = 'labi',        /* label index property */
  41.     formAlias        = typeAlias        /* key desctopr of alias */
  42. };
  43.  
  44. /*
  45.  *--------------------------------------------------------------
  46.  *  static fucntions only used within this source
  47.  *--------------------------------------------------------------
  48.  */
  49. static    OSErr GetFindersDesc(AEDesc *addr);
  50. static    OSErr GetFindersPSN(ProcessSerialNumberPtr psn);
  51. static    OSErr GetAliasDesc(const FSSpecPtr hfs, AEDesc *alias);
  52.  
  53. static    OSErr AskPropertyToFinder(FSSpecPtr hfs, const DescType prop, AppleEvent *reply);
  54. static    OSErr MakeSpecifierForFile(FSSpecPtr hfs, AEDesc *file);
  55. static    OSErr MakePropertySpecifierForSpecifier(DescType prop, AEDesc *spec, AEDesc *propSpec);
  56. static    OSErr BuildIconSuiteFromAEDesc(Handle *suite, AEDesc *family);
  57.  
  58. /*
  59.  *--------------------------------------------------------------
  60.  * GetFindersDesc
  61.  *--------------------------------------------------------------
  62.  *    create finder's address decriptor with its PSN
  63.  *--------------------------------------------------------------
  64.  */
  65. static OSErr GetFindersDesc(AEDesc *findersDesc)
  66. {
  67.     ProcessSerialNumber    findersPSN;
  68.     OSErr    result;
  69.  
  70.     result = GetFindersPSN(&findersPSN);
  71.     if (result == noErr) {
  72.         result = AECreateDesc(typeProcessSerialNumber, &findersPSN, 
  73.             sizeof(ProcessSerialNumber), findersDesc);
  74.     }
  75.     return (result);
  76. }
  77. /*
  78.  *--------------------------------------------------------------
  79.  * GetFindersPSN
  80.  *--------------------------------------------------------------
  81.  *    returns Finder's ProcessSerialNumber
  82.  *--------------------------------------------------------------
  83.  */
  84. static OSErr GetFindersPSN(ProcessSerialNumberPtr thePSN)
  85. {
  86.     ProcessInfoRec    itsInfo;
  87.     OSErr        result;
  88.     FSSpec        itsSpec;
  89.     Str31        itsName;
  90.     int            found;
  91.  
  92.     /* initialize the ProcessSerialNumber */
  93.     thePSN->lowLongOfPSN  = kNoProcess;
  94.     thePSN->highLongOfPSN = kNoProcess;
  95.  
  96.     /* initialize the ProcessInfoRec */
  97.     itsInfo.processInfoLength = sizeof(ProcessInfoRec);
  98.     itsInfo.processName    = itsName;
  99.     itsInfo.processAppSpec = &itsSpec;
  100.  
  101.     do {
  102.         /* search the processes */
  103.         result = GetNextProcess(thePSN);
  104.         if (result == noErr) {
  105.             result = GetProcessInformation(thePSN, &itsInfo);
  106.         }
  107.         /* compare the creators and the types */
  108.         if (result == noErr) {
  109.             found = (itsInfo.processSignature == kFinderSign
  110.                   && itsInfo.processType      == kFinderType);
  111.         } else {
  112.             /* exit this loop in case some error occurred */
  113.             break;
  114.         }
  115.     } while (found == false);
  116.     return (result);
  117. }
  118. /*
  119.  *--------------------------------------------------------------
  120.  * GetAliasDesc
  121.  *--------------------------------------------------------------
  122.  *    returns HFS object's alias descriptor
  123.  *--------------------------------------------------------------
  124.  */
  125. static    OSErr GetAliasDesc(const FSSpecPtr theSpec, AEDesc *theAliasDesc)
  126. {
  127.     AliasHandle    anAlias = nil;
  128.     OSErr        result;
  129.  
  130.     /* create an alias record of the target HFS object */
  131.     result = NewAlias(nil, theSpec, &anAlias);
  132.  
  133.     /* create a list element of the target HFS object */
  134.     if (result == noErr) {
  135.         HLock((Handle)anAlias);
  136.         result = AECreateDesc(typeAlias, *anAlias, GetHandleSize((Handle)anAlias), theAliasDesc);
  137.         DisposeHandle((Handle)anAlias);
  138.     }
  139.     return (result);
  140. }
  141. /*
  142.  *--------------------------------------------------------------
  143.  *    GetIconSuiteViaFinder
  144.  *--------------------------------------------------------------
  145.  *    get an icon suite from the desktop data base using AppleEvent
  146.  *    given handle shoudl be invalid
  147.  *    this routine comes from FinderDrag by DTS, Apple Computer
  148.  *--------------------------------------------------------------
  149.  */
  150. OSErr GetIconSuiteViaFinder(const FSSpecPtr theSpec, Handle *iconSuite)
  151. {
  152.     AppleEvent    replyEvent = { typeNull, nil };
  153.     AEDesc        iconFamily = { typeNull, nil };
  154.     OSErr        result;
  155.  
  156.     /* Set up our locals for easy cleanup */
  157.     *iconSuite = nil;
  158.  
  159.     result = AskPropertyToFinder(theSpec, pIconBitmap, &replyEvent);
  160.  
  161.     if (result == noErr) {        
  162.         /* If not, get the icon family and build an icon suite */
  163.         result = AEGetParamDesc(&replyEvent, keyDirectObject, typeWildCard, &iconFamily);
  164.         if (result == noErr) {
  165.             result = BuildIconSuiteFromAEDesc(iconSuite, &iconFamily);
  166.         }
  167.     }
  168.     /* clean up descriptors */
  169.     (void)AEDisposeDesc(&iconFamily);
  170.     (void)AEDisposeDesc(&replyEvent);
  171.  
  172.     return (result);
  173. }
  174. /*
  175.  *--------------------------------------------------------------
  176.  *    AskPropertyToFinder
  177.  *--------------------------------------------------------------
  178.  *    request a files object's property to finder
  179.  *--------------------------------------------------------------
  180.  */
  181. static OSErr AskPropertyToFinder(
  182.     FSSpecPtr        theSpec,
  183.     const DescType    theProperty,
  184.     AppleEvent *    theAEReply)
  185. {
  186.     AppleEvent    finderEvent = { typeNull, nil };
  187.     AEDesc        finderTarget = { typeNull, nil };
  188.     AEDesc        fileSpecifier = { typeNull, nil };
  189.     AEDesc        propertySpecifier = { typeNull, nil };
  190.     OSErr        result;
  191.  
  192.     result = GetFindersDesc(&finderTarget);
  193.  
  194.     /* make an AppleEvent */
  195.     if (result == noErr) {
  196.         result = AECreateAppleEvent(kAECoreSuite, kAEGetData, &finderTarget, 
  197.             kAutoGenerateReturnID, kAnyTransactionID, &finderEvent);
  198.  
  199.         (void)AEDisposeDesc(&finderTarget);
  200.     }
  201.  
  202.     /* make an object specifier for the interesting file */
  203.     if (result == noErr) {
  204.         result = MakeSpecifierForFile(theSpec, &fileSpecifier);
  205.     }
  206.  
  207.     /* make an icon family property specifier for the file */
  208.     if (result == noErr) {
  209.         result = MakePropertySpecifierForSpecifier(
  210.                     theProperty, &fileSpecifier, &propertySpecifier);
  211.  
  212.         (void)AEDisposeDesc(&fileSpecifier);
  213.     }
  214.  
  215.     /* stuff the icon family property specifier into the AppleEvent */
  216.     if (result == noErr) {
  217.         result = AEPutParamDesc(&finderEvent, keyDirectObject, &propertySpecifier);
  218.  
  219.         (void)AEDisposeDesc(&propertySpecifier);
  220.     }
  221.  
  222.     /* now send the requiest AppleEvent to the Finder */
  223.     if (result == noErr) {
  224.         result = AESend(&finderEvent, theAEReply,
  225.                     kAEWaitReply + kAECanInteract + kAECanSwitchLayer, 
  226.                     kAENormalPriority, kAEDefaultTimeout, nil, nil);
  227.     }
  228.     /* Finder may have sent us an resultor number */
  229.     if (result == noErr) {
  230.         DescType    returnType;
  231.         Size        returnSize;
  232.         long        returnLong;
  233.  
  234.         result = AEGetParamPtr(theAEReply, keyErrorNumber, typeLongInteger, 
  235.                         &returnType, &returnLong, sizeof(long), &returnSize);
  236.         if (result == noErr) {
  237.             result = (OSErr)returnLong;
  238.         } else {
  239.             result = noErr;
  240.         }
  241.     }
  242.     (void)AEDisposeDesc(&finderEvent);
  243.     return (result);
  244. }
  245. /*
  246.  *--------------------------------------------------------------
  247.  *    MakeSpecifierForFile
  248.  *--------------------------------------------------------------
  249.  *    make the object specifier
  250.  *--------------------------------------------------------------
  251.  */
  252. static OSErr MakeSpecifierForFile(FSSpecPtr theSpec, AEDesc *fileSpecifier)
  253. {
  254.     AEDesc        hfsDesc = { typeNull, nil };
  255.     OSErr        result;
  256.  
  257.     /* create the file descriptor with the FSSpec passed in. */
  258.     result = GetAliasDesc(theSpec, &hfsDesc);
  259.  
  260.     /* make the object specifier with a null container
  261.         (i.e., "file of <null>", or just "file") */
  262.     if (result == noErr) {
  263.         AEDesc    nullDesc = { typeNull, nil };
  264.         result = CreateObjSpecifier(typeWildCard, &nullDesc, 
  265.                 formAlias, &hfsDesc, false, fileSpecifier);
  266.     }
  267.     return (result);
  268. }
  269. /*
  270.  *--------------------------------------------------------------
  271.  *    MakePropertySpecifierForSpecifier
  272.  *--------------------------------------------------------------
  273.  *     create a property specifier for the object specifier
  274.  *--------------------------------------------------------------
  275.  */
  276. OSErr MakePropertySpecifierForSpecifier(DescType theProperty, 
  277.             AEDesc *ofSpecifier, AEDesc *propertySpecifier)
  278. {
  279.     AEDesc        keyData = { typeNull, nil };
  280.     OSErr        result;
  281.  
  282.     /* Create a 'type' AEDesc with the desired property */
  283.     result = AECreateDesc(typeType, &theProperty, sizeof(DescType), &keyData);
  284.  
  285.     /* With it create a property specifier for the object specifier passed to us */
  286.     if (result == noErr) {
  287.         result = CreateObjSpecifier(cProperty, ofSpecifier, 
  288.                 formPropertyID, &keyData, false, propertySpecifier);
  289.  
  290.         (void)AEDisposeDesc(&keyData);    
  291.     }
  292.     return result;
  293. }
  294. /*
  295.  *--------------------------------------------------------------
  296.  *    BuildIconSuiteFromAEDesc
  297.  *--------------------------------------------------------------
  298.  *    this uses the Apple Event Manager to pick the icon data
  299.  *    out of the 'ifam' AEDesc
  300.  *--------------------------------------------------------------
  301.  */
  302. static OSErr BuildIconSuiteFromAEDesc(Handle *iconSuite, AEDesc *iconFam)
  303. {
  304.     AERecord    anAERec = { typeNull, nil };
  305.     Ptr            iconBff = nil;
  306.     DescType    typeArray[6] = {
  307.                     large8BitData, large4BitData, large1BitMask,
  308.                     small8BitData, small4BitData, small1BitMask
  309.                 };
  310.     Boolean        maskAdded = false;
  311.     OSErr        result;
  312.  
  313.     /* allocate working buffer */
  314.     iconBff = NewPtr(kLarge8BitIconSize);
  315.     result = MemError();
  316.  
  317.     /* create a  new icon suite */
  318.     if (result == noErr) {    
  319.         result = NewIconSuite(iconSuite);
  320.     }
  321.  
  322.     /* coerce the icon desctiptor to desctiptor record so that
  323.          we can pick up the icon data using AEKeyword */
  324.     if (result == noErr) {    
  325.         result = AECoerceDesc(iconFam, typeAERecord, (AEDesc *)&anAERec);
  326.     }
  327.  
  328.     /* now pick up each icon family */
  329.     if (result == noErr) {    
  330.         int    familyCount;
  331.  
  332.         for (familyCount = 0; familyCount < 6; familyCount ++) {
  333.             /* loop through the suite and grab the data from the AERecord for
  334.             each type of icon we're interested in. */
  335.             DescType    iconType, typeCode;
  336.             Size        iconSize;
  337.  
  338.             iconType = typeArray[familyCount];
  339.             result = AEGetKeyPtr(&anAERec, iconType, iconType, &typeCode, 
  340.                             iconBff, kLarge8BitIconSize, &iconSize);
  341.         
  342.             if (result == noErr) {
  343.                 /* We don't set the error code for this unless the NewHandle
  344.                 call fails, because it's possible that the 'ifam' doesn't
  345.                 have an icon for one that we're interested in. */
  346.                 Handle anIcon = NewHandle(iconSize);
  347.         
  348.                 if (anIcon != nil) {
  349.                     /* OK, the memory alloc succeeded and we have data. Copy
  350.                     it into the allocated icon and add it to the suite. 
  351.                     Set atLeastOne to true, to indicate later that we did
  352.                     in fact add at least one icon to this suite. */
  353.                     BlockMoveData(iconBff, *anIcon, iconSize);
  354.                     result = AddIconToSuite(anIcon, *iconSuite, iconType);
  355.                     if (result == noErr) {
  356.                         if (iconType == large1BitMask) {
  357.                             maskAdded = true;
  358.                         }
  359.                     }
  360.                 } else {
  361.                     result = MemError();
  362.                 }
  363.             }
  364.         }
  365.         (void)AEDisposeDesc(&anAERec);
  366.     }
  367.  
  368.     if ((result != noErr) || (maskAdded == false)) {
  369.         /* There was either an error in a memory allocation, or something
  370.         else went wrong (like no mask was added to the suite).
  371.         Get rid of the partially created suite. */
  372.         if (*iconSuite != nil) {
  373.             DisposeIconSuite(*iconSuite, true);
  374.             *iconSuite = nil;
  375.         }
  376.     }
  377.     if (iconBff != nil) {
  378.         DisposePtr(iconBff);
  379.     }
  380.     return (result);
  381. }
  382. /* end of FIOpen.finder.c */